﻿using System;
using System.Configuration;
using System.Windows.Forms;
using Landpy.CruiseControlNet.ConfigurationSidekick.ConfigPropertyModule;
using Landpy.CruiseControlNet.ConfigurationSidekick.ConfigTreeModule;
using Landpy.CruiseControlNet.ConfigurationSidekick.Resources;
using Landpy.CruiseControlNet.FacadeInterface.ConfigurationModule;
using Landpy.CruiseControlNet.Infrastructure.Control;
using Landpy.CruiseControlNet.Infrastructure.Ioc;

namespace Landpy.CruiseControlNet.ConfigurationSidekick
{
    public partial class MainForm : Form
    {
        #region Member

        private IConfiguration Configuration { get; set; }
        private IGetPropertiesHandler RootHandler { get; set; }
        private TreeDirector TreeManager { get; set; }
        private string FilterString { get; set; }
        private bool IsPropertyChanged { get; set; }

        #endregion

        public MainForm()
        {
            InitializeComponent();
            this.Configuration = IOC.GetInstance().ApplicationContext["Configuration"] as IConfiguration;
            this.RootHandler = TreeNodeProcessChain.GetChain();
            this.FilterString = @"CCNet Config Files|*.config";
            this.IsPropertyChanged = false;
            MultipleTypeCollectionEditor.ValueChangedEvent = this.PropertyGrid_MultipleTypePropertyValueChanged;
            this.LoadTemplates();
        }

        #region Event

        private void PropertyGrid_MultipleTypePropertyValueChanged(object sender, MultipleTypeCollectionEditorEventArgs eventArgs)
        {
            this.IsPropertyChanged = true;
            if (this.ConfigTreeView.SelectedNode != null)
            {
                var childrenNodeContext = new ChildrenNodeContext(
                    this.ConfigTreeView.SelectedNode,
                    eventArgs.EditValue == null
                        ? String.Empty
                        : eventArgs.EditValue.GetType().GetProperty("Item").PropertyType.Name,
                    this.Configuration.CruiseControl);
                ChildrenNodeProcessChain.GetChain().UpdateChildrenNodes(childrenNodeContext);
            }
        }

        private void OpenToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            var openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = this.FilterString;
            DialogResult dialogResult = openFileDialog.ShowDialog();
            if (dialogResult == DialogResult.OK)
            {
                string fileName = openFileDialog.FileName;
                this.LoadTree(fileName);
            }
        }

        private void SaveToolStripMenuItem_Click(object sender, System.EventArgs e)
        {
            var saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = this.FilterString;
            DialogResult dialogResult = saveFileDialog.ShowDialog();
            if (dialogResult == DialogResult.OK)
            {
                string fileName = saveFileDialog.FileName;
                this.SaveConfiguration(fileName);
                this.LoadTree(fileName);
            }
        }

        private void ConfigTreeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            this.LoadProperties(e);
        }

        private void ConfigElementPropertyGrid_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
        {
            this.IsPropertyChanged = true;
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (IsPropertyChanged)
            {
                var confirmResult = MessageBox.Show(Resource.CloseFrom_ConfirmMessage, Resource.CloseFrom_ConfirmTitle, MessageBoxButtons.YesNo);
                if (confirmResult == DialogResult.Yes)
                {
                    e.Cancel = true;
                    SaveToolStripMenuItem_Click(sender, e);
                }
            }
        }

        #endregion

        #region Private Method

        private void LoadTree(string fileName)
        {
            this.ConfigTreeView.Nodes.Clear();
            this.ConfigElementPropertyGrid.SelectedObject = null;
            this.UpdateTree(this.Configuration.Load(fileName));
        }

        private void UpdateTree(CruiseControl cruiseControl)
        {
            this.ConfigTreeView.Nodes.Clear();
            this.TreeManager = new TreeDirector(cruiseControl);
            TreeNode rootTreeNode = this.TreeManager.Load();
            if (rootTreeNode != null)
            {
                this.ConfigTreeView.Nodes.Add(rootTreeNode);
            }
        }

        private void SaveConfiguration(string fileName)
        {
            this.Configuration.Save(fileName, this.Configuration.CruiseControl);
            this.IsPropertyChanged = false;
        }

        private void LoadProperties(TreeViewEventArgs e)
        {
            var getPropertiesContext = new GetPropertiesContext(e.Node, this.Configuration.CruiseControl);
            this.ConfigElementPropertyGrid.SelectedObject = this.RootHandler.GetPropertiesObject(getPropertiesContext);
        }

        private void LoadTemplates()
        {
            foreach (string key in ConfigurationManager.AppSettings.AllKeys)
            {
                var toolStripMenuItem = new ToolStripMenuItem()
                                                  {
                                                      Text = key,
                                                      Tag = ConfigurationManager.AppSettings[key]
                                                  };
                toolStripMenuItem.Click += ToolStripMenuItem_Click;
                this.NewToolStripMenuItem.DropDownItems.Add(toolStripMenuItem);
            }
        }

        private void ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var toolStripMenuItem = sender as ToolStripMenuItem;
            if (toolStripMenuItem != null)
            {
                this.LoadTree(toolStripMenuItem.Tag.ToString());
            }
        }

        #endregion
    }
}
